import axios from 'axios';
import router from '@/plugins/router'
import VueJwtDecode from 'vue-jwt-decode';
import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'


const BASE_URL = 'https://parolus.local/api'

const store = createStore({
    plugins: [createPersistedState({
      paths: ['token', 'userID', 'expiryTimestamp', 'userStatus', 'recievingUsers', 'allUsers', 'passwordData', 'theme', 'appConfig']
    })],
    state() {
        return {
            token: null,
            userID: null,
            expiryTimestamp: null,
            userStatus: null,
            recievingUsers: null,
            allUsers: null,
            passwordData: null,
            theme: null,
            appConfig: null,
        }
    },
    actions: { 
        async login({ commit, dispatch }, { username, password }) {
          try {
            const response = await axios.post(BASE_URL + '/login', {
                username,
                password
            });

            const token = response.data.access_token;
            const userID = VueJwtDecode.decode(token)['sub'];
            const expiryTimestamp = VueJwtDecode.decode(token)['exp'];
            const userStatus = VueJwtDecode.decode(token)['sts'];

            commit('setToken', { token, userID, expiryTimestamp, userStatus });
            dispatch('checkTokenExpiration');

            try {
              const jwtToken = store.state.token;

              const headers = {
                'Authorization': `Bearer ${jwtToken}`
              };

              const response = await axios.get(BASE_URL + '/paroluses/list', { headers });
              const passwordData = response.data.data[0];

              passwordData.forEach(function (element) {
                element.visible = false;
              });

              const response_two = await axios.get(BASE_URL + '/users/list');
              const recievingUsers = response_two.data.data[0].filter(user => user.recievingShares !== false && user.id !== store.state.userID);

              commit('setPasswordData', passwordData);
              commit('setRecievingUsers', recievingUsers);

              } catch (error) {
                  console.error('Error fetching data:', error);
              }

              router.push('/home');

            } catch (error) {
              console.error('Login failed:', error);
              throw error;
            }
          },
          async getPasswordData({ commit }) {
            const jwtToken = store.state.token;
            const headers = {
              'Authorization': `Bearer ${jwtToken}`
            };

            const response = await axios.get(BASE_URL + '/paroluses/list', { headers });
            const passwordData = response.data.data[0];

            passwordData.forEach(function (element) {
              element.visible = false;
            });

            commit('setPasswordData', passwordData);
          },
          async addParolus({ commit }, { title, login, password }) {
            const jwtToken = store.state.token;
            const headers = {
              'Authorization': `Bearer ${jwtToken}`
            };
            await axios.post(BASE_URL + '/paroluses/add', {
              title,
              login,
              password
            }, { headers });

            const response = await axios.get(BASE_URL + '/paroluses/list', { headers });
            const passwordData = response.data.data[0];

            commit('setPasswordData', passwordData);
          },
          async shareParolus({ commit }, { parolus_id, user_id }) {
            try {
              const jwtToken = store.state.token;
              const headers = {
                'Authorization': `Bearer ${jwtToken}`
            };
            await axios.post(BASE_URL + '/paroluses/share/'+parolus_id+'/'+user_id, {
              parolus_id,
              user_id
            }, { headers });

            const response = await axios.get(BASE_URL + '/paroluses/list', { headers });
            const passwordData = response.data.data[0];

            commit('setPasswordData', passwordData);
            } catch(error) {
              if (error.response && error.response.status === 403) {
                console.log('User has blocked receiving function.');
                throw error;
              }
            }
          },
          async getRecieving({ commit }) {
            const jwtToken = store.state.token;
            const headers = {
              'Authorization': `Bearer ${jwtToken}`
            };
            const response = await axios.get(BASE_URL + '/users/recieving', { headers });

            const recievingUsers = response.data.data[0];

            commit('setRecievingUsers', recievingUsers);
          },
          async getAllUsers({ commit }) {
            const response = await axios.get(BASE_URL + '/users/list');
            const allUsers = response.data.data[0];

            commit('setAllUsers', allUsers);
          },
          async editParolus({ commit }, { id, title, login, password }) {
            const jwtToken = store.state.token;
            const headers = {
              'Authorization': `Bearer ${jwtToken}`
            };
            await axios.put(BASE_URL + '/paroluses/'+id, {
              title,
              login,
              password
            }, { headers });

            const response = await axios.get(BASE_URL + '/paroluses/list', { headers });
            const passwordData = response.data.data[0];

            commit('setPasswordData', passwordData);
          },
          async deleteParolus({ commit }, { id }) {
            const jwtToken = store.state.token;
            const headers = {
              'Authorization': `Bearer ${jwtToken}`
            };
            await axios.delete(BASE_URL + '/paroluses/'+id, { headers });

            const response = await axios.get(BASE_URL + '/paroluses/list', { headers });
            const passwordData = response.data.data[0];

            commit('setPasswordData', passwordData);
            router.push('/home');
          },
          async changePassword({ commit }, { new_password }) {
            const jwtToken = store.state.token;
            const headers = {
                'Authorization': `Bearer ${jwtToken}`
            };

            try {
                await axios.put(BASE_URL + '/users/change-password', { new_password }, { headers });
            } catch (error) {
                console.error('Error changing password:', error);
                throw error;
            }
          },
          async newPassword({ commit }, { new_password, updating_user_id }) {
            try {
                await axios.put(BASE_URL + '/users/new-password', { new_password, updating_user_id });
            } catch (error) {
                console.error('Error changing password:', error);
                throw error;
            }
          },
          async changeStatus({ commit }, { new_status }) {
            const jwtToken = store.state.token;
            const headers = {
                'Authorization': `Bearer ${jwtToken}`
            };
            try {
                await axios.put(BASE_URL + '/users/change-status', { new_status }, { headers });
                commit('setStatus', new_status);
            } catch (error) {
                console.error('Error changing status:', error);
                throw error;
            }
          },
          async changeConfig({ commit }, { new_config }) {
            try {
                await axios.put(BASE_URL + '/app-config/change', { new_config });
                commit('setAppConfig', new_config);
            } catch (error) {
                console.error('Error changing config:', error);
                throw error;
            }
          },
          async deleteSelfUserAccount({ commit }) {
            const jwtToken = store.state.token;
            const headers = {
              'Authorization': `Bearer ${jwtToken}`
            };
            await axios.delete(BASE_URL + '/users/delete-self', { headers });

            commit('clearPersistedState');
            router.push('/');
          },
          async deleteUser({ commit }, { uid }) {
            await axios.post(BASE_URL + '/users/delete-one', { uid });
          },
          async getAppConfig({ commit }) {
            const response = await axios.get(BASE_URL + '/app-config');
            const config = response.data.data[0];

            commit('setAppConfig', config);
          },
          logout({ commit }) {
            commit('clearPersistedState');
            router.push('/');
          },
          checkTokenExpiration({ state, dispatch }) {
            const now = Math.floor(Date.now() / 1000);
            const expiryTimestamp = state.expiryTimestamp;

            if (expiryTimestamp && now >= expiryTimestamp) {
                dispatch('logout');
            } else {
                const timeUntilExpiry = expiryTimestamp - now;
                setTimeout(() => {
                    dispatch('checkTokenExpiration');
                }, timeUntilExpiry * 1000);
            }
        },
        async register({ commit }, { username, password }) {
          try {
            await axios.post(BASE_URL + '/users/add', {
                username,
                password
            });
          } catch (error) {
            console.error('Registration failed:', error);
          }
        },
        updateStatus({ commit }, status) {
          commit('setStatus', status);
        },
        updateTheme({ commit }, theme) {
          commit('setTheme', theme);
        },
    },
    mutations: {
          setToken(state, { token, userID, expiryTimestamp, userStatus }) {
            state.token = token;
            state.userID = userID;
            state.expiryTimestamp = expiryTimestamp;
            state.userStatus = userStatus;
          },
          setPasswordData(state, passwordData) {
            state.passwordData = passwordData;
          },
          setTheme(state, theme) {
            state.theme = theme;
          },
          setStatus(state, status) {
            state.userStatus = status;
          },
          setRecievingUsers(state, recievingUsers) {
            state.recievingUsers = recievingUsers;
          },
          setAllUsers(state, allUsers) {
            state.allUsers = allUsers;
          },
          setAppConfig(state, config) {
            state.appConfig = config;
          },
          clearPersistedState(state) {
            state['token'] = null;
            state['userID'] = null;
            state['expiryTimestamp'] = null;
            state['userStatus'] = null;
            state['recievingUsers'] = null,
            state['passwordData'] = null;
          }
    }
})

export default store
